#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include "Log.hpp"
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>


static void Usage(std::string name)
{
    std::cout << "Usage:\n\t" << name << " server_ip server_port" << std::endl;
} 


// ./udpClient IP port
int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        Usage(argv[0]);
        exit(PARA_ERR);
    }
    std::string ip = argv[1];
    uint16_t port = atoi(argv[2]);

    // 2. 创建客户端
    // 2.1 创建socket

    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    assert(sockfd > 0);

    struct sockaddr_in ser;
    bzero(&ser, sizeof ser);
    ser.sin_family = AF_INET;
    ser.sin_port = htons(port);
    ser.sin_addr.s_addr = inet_addr(ip.c_str());

    std::string buffer;
    while(true)
    {
        std::cerr << "Please Enter# ";
        std::getline(std::cin, buffer);
        // 发送消息给server
        sendto(sockfd, buffer.c_str(), buffer.size(), 0,
               (const struct sockaddr *)&ser, sizeof(ser)); // 首次调用sendto函数的时候，我们的client会自动bind自己的ip和port
        
        char inbuffer[1024];
        socklen_t len = sizeof(ser);
        ssize_t s = recvfrom(sockfd, inbuffer, sizeof(inbuffer) - 1, 0,\
            (struct sockaddr *)&ser, &len);
        if(s > 0) 
        {
            //接收成功
            inbuffer[s] = '\0';
        }
        else if(s == -1)
        {
            //
            logMessage(WARINING, "recvfrom fialed:%s[%d]", strerror(errno), sockfd);
            continue;
        }
        std::string peerIp = inet_ntoa(ser.sin_addr);  //拿到对方的ip
        uint32_t peerPort = ntohs(ser.sin_port);  //拿到对方的port
        logMessage(NOTICE, "[%s:%d]# %s", peerIp.c_str(), peerPort, inbuffer);
    }

    close(sockfd);

    return 0;
}